#pragma once

#include <vector>

#include "Types.h"
#include "Chunk.h"



namespace MemMgr
{
	class FixedSizeAllocator
	{
	public:

		typedef std::vector<Chunk> ChunksVec;
		typedef ChunksVec::iterator ChunksIter;
		typedef ChunksVec::const_iterator ChunksCIter;

		FixedSizeAllocator(void);
		FixedSizeAllocator(const FixedSizeAllocator& iOther);
		~FixedSizeAllocator(void);
		FixedSizeAllocator& operator=(const FixedSizeAllocator& iOther);

		inline size_t GetBlockSize(void) const;

		void Swap(FixedSizeAllocator& ioOther);

		void* Allocate(void);
		void Deallocate(void* iPtr);
		void Deallocate(void* iPtr, Chunk* iChunk);
		void Initialize(const size_t iBlockSize, const size_t iPageSize);
		Chunk* SearchChunk(void* iPtr) const;

	private:

		ChunksVec mChunks;

		size_t mBlockSize;
		Chunk::BlockCounter mNumBlocksPerChunk;

		Chunk* mLastAllocationChunk;
		Chunk* mLastDeallocationChunk;
		
		Chunk* mOnlyOneEmptyChunk; // Point to the only empty chunk if there is one... else nullptr.
	};



	inline size_t FixedSizeAllocator::GetBlockSize(void) const
	{
		return mBlockSize;
	}
};